package com.jz.community.basecomm.loaction;

import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.Tip;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.jz.community.basecomm.base.SupportActivity;
import com.jz.community.basecomm.bean.BaseCommLocateInfo;
import com.jz.community.basecomm.bean.LocationInfo;
import com.jz.community.basecomm.utils.BaseSpUtils;
import com.jz.community.basecomm.utils.CommUtils;
import com.jz.community.basecomm.utils.LoggerUtils;
import com.jz.community.basecomm.utils.Preconditions;
import com.jz.community.basecomm.utils.SHelper;
import com.jz.community.basecomm.utils.WpToast;
import com.jz.community.basecommunity.R;

import java.util.ArrayList;
import java.util.List;

/**
 * 定位MapView
 */
public class LocationActivity extends SupportActivity implements LocationSource, AMapLocationListener,
        AMap.OnMapClickListener, View.OnClickListener, Inputtips.InputtipsListener, TextWatcher, AMap.OnCameraChangeListener, PoiSearch.OnPoiSearchListener {
    private AMap aMap;
    private MapView mapView;
    private LocationSource.OnLocationChangedListener mListener;
    private AMapLocationClient aMapLocationClient;
    private AMapLocationClientOption mLocationOption;
    private String TAG = getClass().getSimpleName();
    private boolean isUserClickMap = false;
    private RecyclerView addressListView;
    private LocationAddressAdapter locationAddressAdapter;
    private PoiSearch poiSearch;
    private AutoCompleteTextView et_search_keyword;
    private LinearLayout request_location_address_empty_tip;
    private ImageView iv_not_move_mark;
    private PoiSearch.Query query;
    private TextView search_address;
    private String keyWord;
    private boolean isLocationFlag = false;
    private double lat;
    private double lon;
    private String cityCode = "";
    private BaseCommLocateInfo baseCommLocateInfo;
    private StringBuilder builder = new StringBuilder();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.comm_location);
        initView();
        handleLocationAddressAdapter();
        mapView.onCreate(savedInstanceState);
        aMap = mapView.getMap();
        setUpMap();
        aMap.setOnCameraChangeListener(this);
        aMap.setOnMapTouchListener(motionEvent -> isLocationFlag = true);
        findViewById(R.id.title_back).setOnClickListener(this);
    }

    private void initView() {
        mapView = findViewById(R.id.request_location_map);
        iv_not_move_mark = findViewById(R.id.iv_not_move_mark);
        addressListView = findViewById(R.id.request_location_address_list);
        request_location_address_empty_tip = findViewById(R.id.request_location_address_empty_tip);
        SHelper.vis(request_location_address_empty_tip);
        CommUtils.hideKeyboard(mapView, LocationActivity.this);
    }

    private void handleLocationAddressAdapter() {
        LinearLayoutManager goods_layoutManager = new LinearLayoutManager(this);
        addressListView.setLayoutManager(goods_layoutManager);
        locationAddressAdapter = new LocationAddressAdapter(new ArrayList<>());
        addressListView.setAdapter(locationAddressAdapter);
        locationAddressAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                selectItemAddress(position);
                CommUtils.hideKeyboard(view, LocationActivity.this);
            }
        });
    }

    private void selectItemAddress(int position) {
        List<LocationInfo> locationInfos = locationAddressAdapter.getData();
        for (int i = 0; i < locationInfos.size(); i++) {
            locationInfos.get(i).setSelected(i == position);
        }
        locationAddressAdapter.notifyDataSetChanged();
        iv_not_move_mark.setVisibility(View.VISIBLE);
        for (LocationInfo locationInfo : locationInfos) {
            if (locationInfo.isSelected()) {
                startResultActivity(locationInfo);
                break;
            }
        }
    }

    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
    }

    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {
        lat = cameraPosition.target.latitude;
        lon = cameraPosition.target.longitude;
        if (isLocationFlag){
            searchNearAddress(lat, lon, "");
        }
    }

    /**
     * 设置Map的属性
     */
    private void setUpMap() {
        CameraUpdateFactory.zoomTo(32);
        aMap.setOnMapClickListener(this);
        aMap.setLocationSource(this);// 设置定位监听
        aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        aMap.getUiSettings().setScrollGesturesEnabled(true);
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        search_address = findViewById(R.id.search_address);
        search_address.setOnClickListener(this);
        et_search_keyword = findViewById(R.id.keyWord);
        et_search_keyword.addTextChangedListener(this);// 添加文本输入框监听事件
    }

    /**
     * 定位成功后回调函数
     */
    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (mListener != null && aMapLocation != null) {
            if (aMapLocation != null && aMapLocation.getErrorCode() == 0) {
                if (!isUserClickMap) {
                    isUserClickMap = true;
                    mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点
                    LatLng latLng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                    cityCode = aMapLocation.getCityCode();
                    aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16));
                    if (!Preconditions.isNullOrEmpty(keyWord)) {
                        searchNearAddress(aMapLocation.getLatitude(), aMapLocation.getLongitude(), keyWord);
                    } else {
                        searchNearAddress(aMapLocation.getLatitude(), aMapLocation.getLongitude(), "");
                    }
                }
            } else {
                String errText = "定位失败," + aMapLocation.getErrorCode() + ": " + aMapLocation.getErrorInfo();
                LoggerUtils.fLog().i(errText);
                if (aMapLocationClient != null) {
                    aMapLocationClient.stopLocation();
                }
            }
        }
    }

    @Override
    public void activate(OnLocationChangedListener listener) {
        mListener = listener;
        if (aMapLocationClient == null) {
            aMapLocationClient = new AMapLocationClient(this);
            mLocationOption = new AMapLocationClientOption();
            aMapLocationClient.setLocationListener(this);
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            aMapLocationClient.setLocationOption(mLocationOption);
            aMapLocationClient.startLocation();
        }
    }

    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (aMapLocationClient != null) {
            aMapLocationClient.stopLocation();
            aMapLocationClient.onDestroy();
        }
        aMapLocationClient = null;
    }

    @Override
    public void onMapClick(LatLng latLng) {
        isUserClickMap = true;
        searchNearAddress(latLng.latitude, latLng.longitude, "");
    }

    @Override
    public void afterTextChanged(Editable s) {

    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
                                  int after) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        String newText = s.toString().trim();
        if (!Preconditions.isNullOrEmpty(newText)) {
            searchKeyWordAddress(newText);
        }
    }

    private void searchButton() {
        keyWord = et_search_keyword.getText().toString();
        if (Preconditions.isNullOrEmpty(keyWord)) {
            WpToast.l(this, "请输入搜索关键字");
            return;
        } else {
            searchKeyWordAddress(keyWord);
        }
    }

    /**
     * 搜索附近经纬度关联地址
     *
     * @param latitude
     * @param longitude
     * @param keyWord
     */
    public void searchNearAddress(double latitude, double longitude, String keyWord) {
        setQueryParam(latitude, longitude, keyWord, true);
    }

    /**
     * 搜索关键字关联地址
     *
     * @param keyWord
     */
    public void searchKeyWordAddress(String keyWord) {
        setQueryParam(0, 0, keyWord, false);
    }

    /**
     * 设置查询条件参数
     *
     * @param latitude
     * @param longitude
     * @param keyWord
     * @param isKeyWord
     */
    private void setQueryParam(double latitude, double longitude, String keyWord, boolean isKeyWord) {
        SHelper.vis(request_location_address_empty_tip);
        query = new PoiSearch.Query(keyWord, "", cityCode);
        query.setPageSize(50); // 设置每页最多返回多少条poiitem
        query.setPageNum(0);
        poiSearch = new PoiSearch(this, query);
        poiSearch.setOnPoiSearchListener(this);
        if (isKeyWord) {
            LatLonPoint point = new LatLonPoint(latitude, longitude);
            poiSearch.setBound(new PoiSearch.SearchBound(point, 2000, true));//搜索周边
        }
        poiSearch.searchPOIAsyn();
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.title_back) {
            setResult(RESULT_CANCELED);
            CommUtils.hideKeyboard(v, this);
            finish();
        }
        if (v.getId() == R.id.search_address) {
            searchButton();
        }
    }

    /**
     * 跳转 -》Result
     *
     * @param locationInfo
     */
    private void startResultActivity(LocationInfo locationInfo) {
        if (!Preconditions.isNullOrEmpty(locationInfo)) {
            baseCommLocateInfo = new BaseCommLocateInfo();
            baseCommLocateInfo.city = locationInfo.getCityName();
            baseCommLocateInfo.citycode = locationInfo.getCityCode();
            baseCommLocateInfo.lat = locationInfo.getLatitude() + "";
            baseCommLocateInfo.lon = locationInfo.getLongitude() + "";
            baseCommLocateInfo.name = locationInfo.getTitle();
            baseCommLocateInfo.area = locationInfo.getArea();
            baseCommLocateInfo.areaCode = locationInfo.getAreaCode();
            baseCommLocateInfo.provinceName = locationInfo.getProvinceName();
            baseCommLocateInfo.provinceCode = locationInfo.getProvinceCode();
            baseCommLocateInfo.snippet=locationInfo.getSnippet();
            baseCommLocateInfo.address = locationInfo.getAddress();
        }
        Intent intent = new Intent();
        if (!Preconditions.isNullOrEmpty(baseCommLocateInfo)) {
            intent.putExtra("comm_location", (Parcelable) baseCommLocateInfo);
        }
        BaseSpUtils.getInstance().setCurrentCommuity(this, baseCommLocateInfo);
        setResult(RESULT_OK, intent);
        BaseSpUtils.getInstance().putBoolean(this, "isSelectShipAddress", false);
        finish();
    }

    @Override
    public void onGetInputtips(List<Tip> list, int i) {
        Log.i("List", list + "");
        Log.i("List", list.get(0).getAddress() + "");
    }

    @Override
    public void onPoiSearched(PoiResult poiResult, int j) {
        if (j == AMapException.CODE_AMAP_SUCCESS) {
            SHelper.gone(request_location_address_empty_tip);
            List<LocationInfo> locationInfos = new ArrayList<>();
            List<PoiItem> list = poiResult.getPois();
            for (int i = 0; i < list.size(); i++) {
                PoiItem item = list.get(i);
                cityCode = item.getCityCode();
                // 西安市
                String cityName = item.getCityName();
                // 陕西省
                String provinceName = item.getProvinceName();
                String provinceCode = item.getProvinceCode();
                String title = item.getTitle();
                String area = item.getAdName();
                String areaCode = item.getAdCode();
                String snippet = item.getSnippet();
                builder.delete(0, builder.length());
                builder.append(cityName).append(" ").append(area).append(" ").append(snippet);
                LocationInfo locationInfo = new LocationInfo();
                locationInfo.setAddress(builder.toString());
                locationInfo.setTitle(title);
                locationInfo.setCityCode(cityCode);
                locationInfo.setSnippet(snippet);
                locationInfo.setArea(area);
                locationInfo.setAreaCode(areaCode);
                locationInfo.setProvinceName(provinceName);
                locationInfo.setProvinceCode(provinceCode);
                locationInfo.setCityName(cityName);
                locationInfo.setLatitude(item.getLatLonPoint().getLatitude());
                locationInfo.setLongitude(item.getLatLonPoint().getLongitude());
                locationInfos.add(locationInfo);
            }
            runOnUiThread(() -> {
                isLocationFlag = false;
                if (locationInfos.size() > 0) {
                    locationInfos.get(0).setSelected(true);
                    locationAddressAdapter.setNewData(locationInfos);
                    aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(locationInfos.get(0).getLatitude(), locationInfos.get(0).getLongitude()), 16));
                } else {
                    locationAddressAdapter.setNewData(locationInfos);
                }
            });
        }
    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }


    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
        deactivate();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }
}